package com.itheima.easy.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.itheima.easy.base.PageResponse;
import com.itheima.easy.constant.SuperConstant;
import com.itheima.easy.entity.DeptPostUser;
import com.itheima.easy.entity.Post;
import com.itheima.easy.entity.User;
import com.itheima.easy.entity.UserRole;
import com.itheima.easy.mapper.PostMapper;
import com.itheima.easy.mapper.UserMapper;
import com.itheima.easy.properties.SecurityConfigProperties;
import com.itheima.easy.service.*;
import com.itheima.easy.utils.BeanConv;
import com.itheima.easy.utils.EmptyUtil;
import com.itheima.easy.utils.NoProcessing;
import com.itheima.easy.utils.ObjectUtil;
import com.itheima.easy.vo.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Description：用户表服务实现类
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    UserMapper userMapper;

    @Autowired
    RoleService roleService;

    @Autowired
    DeptPostUserService deptPostUserService;

    @Autowired
    UserRoleService userRoleService;

    @Autowired
    BCryptPasswordEncoder bCryptPasswordEncoder;

    @Resource
    DeptService deptService;

    @Resource
    PostMapper postMapper;


    @Override
    public PageResponse<UserVo> findUserPage(UserVo userVo, int pageNum, int pageSize) {
        //构建分页对象
        PageHelper.startPage(pageNum, pageSize);
        if (!EmptyUtil.isNullOrEmpty(userVo.getDeptNo())){
            userVo.setDeptNo(NoProcessing.processString(userVo.getDeptNo()));
        }
        Page<List<User>> page = userMapper.selectPage(userVo);
        PageResponse<UserVo> pageResponse = PageResponse.of(page, UserVo.class);
        if (!EmptyUtil.isNullOrEmpty(pageResponse.getRecords())){
            List<Long> userIds = pageResponse.getRecords().stream().map(UserVo::getId).collect(Collectors.toList());
            //查询对应角色
            List<RoleVo> roleVoList = roleService.findRoleVoListInUserId(userIds);
            //查询对应部门、职位
            List<DeptPostUserVo> deptPostUserVoList = deptPostUserService.findDeptPostUserVoListInUserId(userIds);

            // 查询部门职位
            List<DeptVo> deptInDeptNos = deptService.findDeptInDeptNos(deptPostUserVoList.stream().map(DeptPostUserVo::getDeptNo).distinct().collect(Collectors.toList()));
            Map<String, String> map = deptInDeptNos.stream().collect(Collectors.toMap(DeptVo::getDeptNo, DeptVo::getDeptName));
            //装配数据
            pageResponse.getRecords().forEach(n->{
                //装配角色
                Set<String> roleVoIds = Sets.newHashSet();
                //
                Set<String> roleVoLabels = Sets.newHashSet();
                roleVoList.forEach(r->{
                    if (String.valueOf(n.getId()).equals(r.getUserId())){
                        roleVoIds.add(String.valueOf(r.getId()));
                        roleVoLabels.add(r.getRoleName());

                    }
                });
                n.setRoleLabels(roleVoLabels);
                n.setRoleVoIds(roleVoIds);
                //装配对应部门、职位、数据权限
                Set<DeptPostUserVo> deptPostUserVoSet = Sets.newHashSet();
                deptPostUserVoList.forEach(r->{
                    if (String.valueOf(n.getId()).equals(String.valueOf(r.getUserId()))){
                        deptPostUserVoSet.add(r);
                        String s = map.get(r.getDeptNo());
                        n.setDept(s);
                        Post post = postMapper.selectByPostNo(r.getPostNo());
                        if (ObjectUtil.isNotEmpty(post)) {
                            n.setPost(post.getPostName());
                        }
                    }
                });
                n.setDeptPostUserVoSet(deptPostUserVoSet);
            });
        }
        return pageResponse;
    }


    @Autowired
    SecurityConfigProperties securityConfigProperties;

    @Override
    @Transactional
    public UserVo createUser(UserAddVo userVo) {
        String password = bCryptPasswordEncoder.encode(securityConfigProperties.getDefaulePassword());
        userVo.setPassword(password);
        //转换UserVo为User
        User user = BeanConv.toBean(userVo, User.class);
        user.setUsername(user.getEmail());
        user.setNickName(user.getRealName());
        int flag = userMapper.insert(user);
        if (flag==0){
            throw new RuntimeException("保存用户信息出错");
        }
        //保存用户角色中间表
        List<UserRole> userRoles = Lists.newArrayList();
        userVo.getRoleVoIds().forEach(r->{
            userRoles.add(UserRole.builder()
                .userId(user.getId())
                .roleId(Long.valueOf(r))
                .dataState(SuperConstant.DATA_STATE_0)
                .build());
        });
        flag = userRoleService.batchInsert(userRoles);
        if (flag==0){
            throw new RuntimeException("保存用户角色中间表出错");
        }
        //保存部门职位中间表
        List<DeptPostUser> deptPostUsers = Lists.newArrayList();
        DeptPostUser dpu = new DeptPostUser();
        dpu.setUserId(user.getId());
        dpu.setDeptNo(userVo.getDeptNo());
        dpu.setPostNo(userVo.getPostNo());
        dpu.setDataState(SuperConstant.DATA_STATE_0);
        deptPostUsers.add(BeanConv.toBean(dpu,DeptPostUser.class));

        flag = deptPostUserService.batchInsert(deptPostUsers);
        if (flag==0){
            throw new RuntimeException("保存部门职位中间表出错");
        }
        return BeanConv.toBean(user, UserVo.class);
    }

    @Override
    @Transactional
    public Boolean updateUser(UserAddVo userVo) {
        //转换UserVo为User
        User user = BeanConv.toBean(userVo, User.class);
        int flag = userMapper.updateByPrimaryKeySelective(user);
        if (flag==0){
            throw new RuntimeException("修改用户信息出错");
        }


        if (CollUtil.isNotEmpty(userVo.getRoleVoIds())) {
            //删除角色中间表
            boolean flagDel = userRoleService.deleteUserRoleByUserId(user.getId());
            if (!flagDel){
                throw new RuntimeException("删除角色中间表出错");
            }

            //重新保存角色中间表
            List<UserRole> userRoles = Lists.newArrayList();
            userVo.getRoleVoIds().forEach(r->{
                userRoles.add(UserRole.builder()
                        .userId(user.getId())
                        .roleId(Long.valueOf(r))
                        .dataState(SuperConstant.DATA_STATE_0)
                        .build());
            });
            flag = userRoleService.batchInsert(userRoles);
            if (flag==0){
                throw new RuntimeException("保存角色中间表出错");
            }
        }

        if (ObjectUtil.isNotEmpty(userVo.getPostNo())) {
            //删除部门职位中间表
            boolean flagDel = deptPostUserService.deleteDeptPostUserByUserId(user.getId());
            if (!flagDel){
                throw new RuntimeException("删除角色中间表出错");
            }
            //重新保存部门职位中间表
            List<DeptPostUser> deptPostUsers = Lists.newArrayList();
            DeptPostUser dpu = new DeptPostUser();
            dpu.setUserId(user.getId());
            dpu.setDeptNo(userVo.getDeptNo());
            dpu.setPostNo(userVo.getPostNo());
            dpu.setDataState(SuperConstant.DATA_STATE_0);
            deptPostUsers.add(BeanConv.toBean(dpu,DeptPostUser.class));

            flag = deptPostUserService.batchInsert(deptPostUsers);
            if (flag==0){
                throw new RuntimeException("保存部门职位中间表出错");
            }
        }

        return true;
    }

    @Override
    public List<UserVo> findUserList(UserVo userVo) {
        if (!EmptyUtil.isNullOrEmpty(userVo.getDeptNo())){
            userVo.setDeptNo(NoProcessing.processString(userVo.getDeptNo()));
        }
        List<User> userList = userMapper.selectList(userVo);
        List<UserVo> userVoList = BeanConv.toBeanList(userList, UserVo.class);
        if (!EmptyUtil.isNullOrEmpty(userVoList)){
            List<Long> userIdSet = userVoList.stream().map(UserVo::getId).collect(Collectors.toList());
            //查询对应角色
            List<RoleVo> roleVoList = roleService.findRoleVoListInUserId(userIdSet);
            //查询对应部门、职位、数据权限
            List<DeptPostUserVo> deptPostUserVoList = deptPostUserService.findDeptPostUserVoListInUserId(userIdSet);
            //装配数据
            userVoList.forEach(n->{
                //装配角色
                Set<String> roleVoIds = Sets.newHashSet();
                roleVoList.forEach(r->{
                    if (String.valueOf(n.getId()).equals(r.getUserId())){
                        roleVoIds.add(String.valueOf(r.getId()));
                    }
                });
                n.setRoleVoIds(roleVoIds);
                //装配对应部门、职位、数据权限
                Set<DeptPostUserVo> deptPostUserVoSet = Sets.newHashSet();
                deptPostUserVoList.forEach(r->{
                    if (String.valueOf(n.getId()).equals(String.valueOf(r.getUserId()))){
                        deptPostUserVoSet.add(r);
                    }
                });
                n.setDeptPostUserVoSet(deptPostUserVoSet);
            });
        }
        return userVoList;
    }

    @Override
    public  List<UserVo> findUserVoListByDeptNo(String deptNo) {
        return userMapper.findUserVoListByDeptNo(deptNo);
    }

    @Override
    public  List<UserVo> findUserVoListByPostNo(String postNo) {
        return userMapper.findUserVoListByPostNo(postNo);
    }

    @Override
    public List<UserVo> findUserVoListByRoleId(Long roleId) {
        return userMapper.findUserVoListByRoleId(roleId);
    }

    @Override
    public UserVo findUserVoForLogin(String username, String openId, String mobile) {
        UserVo userVo = UserVo.builder()
            .username(username)
            .openId(openId)
            .mobile(mobile)
            .dataState(SuperConstant.DATA_STATE_0)
            .build();
        User user = userMapper.findUserVoForLogin(userVo);
        if (!EmptyUtil.isNullOrEmpty(user)){
            UserVo vo = new UserVo();
            BeanUtils.copyProperties(user, vo);
            return vo;
        }
        throw  new RuntimeException("用户登录失败");
    }

    @Override
    public Boolean resetPasswords(String userId) {
        String password = bCryptPasswordEncoder.encode(securityConfigProperties.getDefaulePassword());
        User user = User.builder().id(Long.valueOf(userId)).password(password).build();
        int flag = userMapper.updateByPrimaryKeySelective(user);
        if (flag>0){
            return true;
        }
        return false;
    }

    @Override
    public int deleteUserByIds(List<Long> userIds) {
//        for (Long userId : userIds) {
//            checkUserAllowed(new SysUser(userId));
//        }
        // 删除用户与角色关联
        userRoleService.deleteUserRoleInUserId(userIds);
        // 删除用户与岗位关联
        deptPostUserService.deleteDeptPostUserInUserId(userIds);
        return userMapper.deleteUserByIds(userIds);
    }
}
